#include "mesh.h"
#include "resourcemanager.h"

Mesh::Mesh()
{
    core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
}

Mesh::~Mesh()
{
    core->glDeleteVertexArrays(1, &VAO);
    core->glDeleteBuffers(1, &VBO);
    core->glDeleteBuffers(1, &EBO);
}

GLboolean Mesh::init()
{
    core->glGenVertexArrays(1, &VAO);
    core->glGenBuffers(1, &VBO);
    core->glGenBuffers(1, &EBO);

    core->glBindVertexArray(VAO);

    core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    core->glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);

    core->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    core->glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);

    // 顶点位置
    core->glEnableVertexAttribArray(0);
    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)0);
//    // 顶点法线
//    core->glEnableVertexAttribArray(1);
//    core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, normal));
//    // 顶点纹理坐标
//    core->glEnableVertexAttribArray(2);
//    core->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, texCoords));
//    // vertex tangent
//    core->glEnableVertexAttribArray(3);
//    core->glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, tangent));
//    // vertex bitangent
//    core->glEnableVertexAttribArray(4);
//    core->glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, bitangent));

//    core->glBindVertexArray(0);

    return GL_TRUE;
}

void Mesh::draw()
{
    unsigned int diffuseNr = 1;
    unsigned int specularNr = 1;
    unsigned int normalNr = 1;
    unsigned int heightNr = 1;

    for (int i = 0; i < textures.size(); ++i)
    {
        // 获取纹理序号（diffuse_textureN 中的 N）
        unsigned int number;
        QString name = textures[i].type;
        if (name == "texture_diffuse")
            number = diffuseNr++;
        else if (name == "texture_specular")
            number = specularNr++;
        else if (name == "texture_normal")
            number = normalNr++;
        else if (name == "texture_height")
            number = heightNr++;

//        // now set the sampler to the correct texture unit
//        glUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i);
//        // and finally bind the texture
//        glBindTexture(GL_TEXTURE_2D, textures[i].id);

        // 激活纹理单元
        core->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
        ResourceManager::getShader("object")->use().setFloat(("material." + name + QString::number(number)), i);
        ResourceManager::getTexture(textures[i].path)->bind();
    }

    // 绘制网格
    core->glBindVertexArray(VAO);
    core->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
//    core->glBindVertexArray(0);

    // always good practice to set everything back to defaults once configured.
//    core->glActiveTexture(GL_TEXTURE0);
}
